<?php

namespace addons\csmitsm\library\xcore\xcore\utils;

use addons\csmitsm\library\xcore\xcore\XcException;
use think\Db;
use Exception;

/**
 * 方法一(推荐)
        XcTransactionUtils::service(function() use($param){
            // return call method
        });
 * 方法二(多参数、多返回值)
        $ts = XcTransactionUtils::begin();
        try{
            // call method
            $ts->commit();
        }catch(Exception $e){
            $ts->rollback($e);
        }
 */
class XcTransactionUtils
{
    /**
     * @return Instance
     */
    public static function begin()
    {
        Db::startTrans();
        return new Instance();
    }

    public static function service($callback){
        $result = null;
        Db::startTrans();
        try{
            $result = $callback();

            Db::commit();
        }catch(XcException $e){
            Db::rollback();
            XcResponseUtils::error($e->getMessage());
        }catch(Exception $e){
            Db::rollback();

            $debug = XcConfigUtils::systemconfig("app_debug");
            if ($debug === true) {
                throw $e;
            } else {
                XcResponseUtils::error($e->getMessage());
            }
        }
        return $result;
    }
}


class Instance{
    public function commit()
    {
        Db::commit();
    }

    public function rollback($e)
    {
        Db::rollback();

        $debug = XcConfigUtils::systemconfig("app_debug");
        if ($debug === true) {
            throw $e;
        } else {
            XcResponseUtils::error($e->getMessage());
        }
    }
}